{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Reading Values from Touch Keypad\n",
    "\n",
    "This demonstration shows how to interact with the Raspberry Pi Touch Keypad.\n",
    "The Raspberry Pi Touch Keypad is required (https://www.seeedstudio.com/Raspberry-Pi-Touch-Keypad-p-2772.html).\n",
    "\n",
    "![](data/rpi_touchpad.jpg)\n",
    "\n",
    "The Raspberry Pi touch keypad supports up to 16 keys with adjustable \n",
    "sensitivity and built-in LD0.\n",
    "Touch keypad is read only, and has IIC interface\n",
    "connected to SDA1 and SCL1 on the Raspberry Pi interface.\n",
    "The I2C will read 2 bytes of data: `Data_0` and `Data_1`.\n",
    "* `Data_0`: B7 ~ B0 is TP0 ~ TP7 on/off status. 0 is key off, 1 is key on.\n",
    "* `Data_1`: B7 ~ B0 is TP8 ~ TP15 on/off status. 0 is key off, 1 is key on.\n",
    "\n",
    "### 1. Prepare the overlay\n",
    "Download the overlay first, then select the shared pin to be connected to\n",
    "RPI header (by default, the pins will be connected to PMODA instead)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "\n",
       "require(['notebook/js/codecell'], function(codecell) {\n",
       "  codecell.CodeCell.options_default.highlight_modes[\n",
       "      'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n",
       "  Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n",
       "      Jupyter.notebook.get_cells().map(function(cell){\n",
       "          if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n",
       "  });\n",
       "});\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from pynq.overlays.base import BaseOverlay\n",
    "\n",
    "base = BaseOverlay(\"base.bit\")\n",
    "base.select_rpi()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. Instantiate the Microblaze\n",
    "The Microblaze will control the pins on the RASPBERRYPI header."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%microblaze base.RPI\n",
    "\n",
    "#include \"xio_switch.h\"\n",
    "#include \"circular_buffer.h\"\n",
    "#include \"i2c.h\"\n",
    "\n",
    "// Device constants\n",
    "#define TOUCHPAD_DEV_ADDRESS         0x57\n",
    "\n",
    "unsigned int get_touchpad_reg_value(){\n",
    "    uint8_t data[2];\n",
    "    i2c device = i2c_open_device(1);\n",
    "    set_pin(2, SDA1);\n",
    "    set_pin(3, SCL1);\n",
    "    i2c_read(device, TOUCHPAD_DEV_ADDRESS, data, 2);\n",
    "    return (unsigned int) ((data[0] << 8) + data[1]);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. Read the key values\n",
    "The available pin names are listed below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "PIN_MAPPING = {'circle': 0,\n",
    "               'cross': 1,\n",
    "               'square': 2,\n",
    "               'r': 3,\n",
    "               'home': 4,\n",
    "               '+': 5,\n",
    "               '-': 6,\n",
    "               'l': 7,\n",
    "               'down': 8,\n",
    "               'right': 9,\n",
    "               'up': 10,\n",
    "               'left': 11,\n",
    "               'power': 12,\n",
    "               'rpi': 13,\n",
    "               'logo': 14,\n",
    "               'triangle': 15\n",
    "               }"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To convert the raw data into the value for each key, we define the following\n",
    "functions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def reg2int(reg_value, key_number):\n",
    "    return \"{0:b}\".format(reg_value).zfill(16)[-(key_number+1)]\n",
    "\n",
    "def get_touchpad(key_name):\n",
    "    reg_value = get_touchpad_reg_value()\n",
    "    key_number = PIN_MAPPING[key_name]\n",
    "    return reg2int(reg_value, key_number)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Run the following code without pressing any button."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'0'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_touchpad('home')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "While pressing gently on the home button of the touch keypad, run the following code."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'1'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_touchpad('home')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "While pressing the right arrow and square at the same time, \n",
    "run the following code. Note that there are 2 read commands issued,\n",
    "although 1 read command can get values for all the keys."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Key right reads value 1.\n",
      "Key square reads value 1.\n"
     ]
    }
   ],
   "source": [
    "for key in ['right', 'square']:\n",
    "    print('Key {} reads value {}.'.format(key, get_touchpad(key)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4. Cleanup\n",
    "Switch back the connection on the shared pin to PMODA header."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "base.select_pmoda()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
